package com.ibeeking.found.content.b.rest.service.impl;

import cn.binarywang.wx.miniapp.bean.live.WxMaLiveGoodInfo;
import cn.binarywang.wx.miniapp.bean.live.WxMaLiveResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.common.response.ResponseCodeEnum;
import com.ibeeking.found.common.utils.DataUtils;
import com.ibeeking.found.common.utils.NumberUtils;
import com.ibeeking.found.common.utils.UserUtils;

import com.ibeeking.found.content.api.common.dto.GoodsDTO;

import com.ibeeking.found.content.api.feign.ContentGoodsBClient;
import com.ibeeking.found.content.b.rest.service.IBroadcastGoodsService;
import com.ibeeking.found.content.b.rest.service.IWxBroadcastService;
import com.ibeeking.found.content.service.common.constants.enums.BroadcastGoodsPriceTypeEnum;
import com.ibeeking.found.content.service.common.dos.BroadcastGoodsDO;
import com.ibeeking.found.content.service.common.param.BroadcastGoodsParam;
import com.ibeeking.found.content.service.common.query.BroadcastGoodsPageQuery;
import com.ibeeking.found.content.service.common.query.BroadcastGoodsQuery;
import com.ibeeking.found.content.service.common.vo.BroadcastGoodsVO;
import com.ibeeking.found.content.service.mapper.BroadcastGoodsMapper;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.id.IdGenerator;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.ibeeking.nematos.utils.result.ResponseResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class BroadcastGoodsServiceImpl extends ServiceImpl<BroadcastGoodsMapper, BroadcastGoodsDO> implements IBroadcastGoodsService {

    @Resource
    private IWxBroadcastService wxBroadcastServiceImpl;

    @Resource
    private BroadcastGoodsMapper broadcastGoodsMapper;

    @Resource
    private ContentGoodsBClient goodsFeignBClient;

    @Override
    public List<BroadcastGoodsVO> list(BroadcastGoodsQuery query) {
        LambdaQueryWrapper<BroadcastGoodsDO> queryWrapper = new LambdaQueryWrapper<BroadcastGoodsDO>()
                .eq(query.getId() != null, BroadcastGoodsDO::getId, query.getId())
                .eq(query.getGoodsId() != null, BroadcastGoodsDO::getGoodsId, query.getGoodsId())
                .eq(query.getGoodsPriceType() != null, BroadcastGoodsDO::getGoodsPriceType, query.getGoodsPriceType())
                .in(StringUtils.isNotEmpty(query.getGoodsName()), BroadcastGoodsDO::getGoodsName, query.getGoodsName())
                .eq(query.getAuditId() != null, BroadcastGoodsDO::getAuditId, query.getAuditId())
                .eq(query.getPublishStatus() != null, BroadcastGoodsDO::getPublishStatus, query.getPublishStatus())
                .orderByDesc(BroadcastGoodsDO::getCreateTime);
        List<BroadcastGoodsDO> broadcastGoodsDOs = broadcastGoodsMapper.selectList(queryWrapper);
        List<BroadcastGoodsVO> broadcastGoodsVOS = new ArrayList<>();
        broadcastGoodsVOS = broadcastGoodsDOs.stream().map(d->{
            BroadcastGoodsVO broadcastGoodsVO = BeanUtil.convertBean(d, BroadcastGoodsVO.class);
            broadcastGoodsVO.setGoodsPriceTypeName(BroadcastGoodsPriceTypeEnum.getNameByValue(d.getGoodsPriceType()));
            if(BroadcastGoodsPriceTypeEnum.PRICE_TYPE_FIXED.getValue() == d.getGoodsPriceType()) {
                BigDecimal fGoodsPrice= NumberUtils.cent2Yuan(d.getGoodsPrice());
                broadcastGoodsVO.setGoodsPriceDesc(fGoodsPrice.toPlainString());
            }else if(BroadcastGoodsPriceTypeEnum.PRICE_TYPE_DISCOUNT.getValue() == d.getGoodsPriceType()){
                BigDecimal fGoodsPrice= NumberUtils.cent2Yuan(d.getGoodsPrice2());
                broadcastGoodsVO.setGoodsPriceDesc(fGoodsPrice.toPlainString());
            }else if(BroadcastGoodsPriceTypeEnum.PRICE_TYPE_SECTION.getValue() == d.getGoodsPriceType()){
                BigDecimal fGoodsPrice= NumberUtils.cent2Yuan(d.getGoodsPrice());
                BigDecimal fGoodsPrice2= NumberUtils.cent2Yuan(d.getGoodsPrice2());
                broadcastGoodsVO.setGoodsPriceDesc(fGoodsPrice.toPlainString()+"~"+fGoodsPrice2.toPlainString());
            }
            broadcastGoodsVO.setPublishStatusDesc(PublishStatusEnum.getName(d.getPublishStatus()));
            return broadcastGoodsVO;
        }).collect(Collectors.toList());
        return broadcastGoodsVOS;
    }

    @Override
    public Page<BroadcastGoodsVO> pageList(BroadcastGoodsPageQuery pageQuery) {
        LambdaQueryWrapper<BroadcastGoodsDO> queryWrapper = new LambdaQueryWrapper<BroadcastGoodsDO>()
                .eq(pageQuery.getId() != null, BroadcastGoodsDO::getId, pageQuery.getId())
                .eq(pageQuery.getGoodsId() != null, BroadcastGoodsDO::getGoodsId, pageQuery.getGoodsId())
                .eq(pageQuery.getGoodsPriceType() != null, BroadcastGoodsDO::getGoodsPriceType, pageQuery.getGoodsPriceType())
                .in(StringUtils.isNotEmpty(pageQuery.getGoodsName()), BroadcastGoodsDO::getGoodsName, pageQuery.getGoodsName())
                .eq(pageQuery.getAuditId() != null, BroadcastGoodsDO::getAuditId, pageQuery.getAuditId())
                .eq(pageQuery.getPublishStatus() != null, BroadcastGoodsDO::getPublishStatus, pageQuery.getPublishStatus())
                .orderByDesc(BroadcastGoodsDO::getCreateTime);

        Page<BroadcastGoodsDO> pages = broadcastGoodsMapper.selectPage(new Page<BroadcastGoodsDO>(pageQuery.getPageNum(), pageQuery.getPageSize()), queryWrapper);
        Page<BroadcastGoodsVO> broadcastGoodsVOPage = BeanUtil.convertPage(pages, BroadcastGoodsVO.class);
        List<BroadcastGoodsVO> records = broadcastGoodsVOPage.getRecords();
        if (Collections3.isNotEmpty(records)) {
            records.stream().forEach(d->{
                d.setGoodsPriceTypeName(BroadcastGoodsPriceTypeEnum.getNameByValue(d.getGoodsPriceType()));
                if(BroadcastGoodsPriceTypeEnum.PRICE_TYPE_FIXED.getValue() == d.getGoodsPriceType()) {
                    BigDecimal fGoodsPrice= NumberUtils.cent2Yuan(d.getGoodsPrice());
                    d.setGoodsPriceDesc(fGoodsPrice.toPlainString());
                }else if(BroadcastGoodsPriceTypeEnum.PRICE_TYPE_DISCOUNT.getValue() == d.getGoodsPriceType()){
                    BigDecimal fGoodsPrice= NumberUtils.cent2Yuan(d.getGoodsPrice2());
                    d.setGoodsPriceDesc(fGoodsPrice.toPlainString());
                }else if(BroadcastGoodsPriceTypeEnum.PRICE_TYPE_SECTION.getValue() == d.getGoodsPriceType()){
                    BigDecimal fGoodsPrice= NumberUtils.cent2Yuan(d.getGoodsPrice());
                    BigDecimal fGoodsPrice2= NumberUtils.cent2Yuan(d.getGoodsPrice2());
                    d.setGoodsPriceDesc(fGoodsPrice.toPlainString()+"~"+fGoodsPrice2.toPlainString());
                }
                d.setPublishStatusDesc(PublishStatusEnum.getName(d.getPublishStatus()));
            });
            broadcastGoodsVOPage.setRecords(records);
        }
        return broadcastGoodsVOPage;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean add(BroadcastGoodsParam param) {
        checkUnique(param);
        BroadcastGoodsDO broadcastGoodsDO = BeanUtil.convertBean(param, BroadcastGoodsDO.class);
        broadcastGoodsDO.setCreateBy(UserUtils.getUserId());
        broadcastGoodsDO.setCreateTime(LocalDateTime.now());
        broadcastGoodsDO.setModifyTime(LocalDateTime.now());
        return broadcastGoodsMapper.insert(broadcastGoodsDO) > 0;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean batchAdd(List<String> goodsIdList) {
         List<Long> goodsIds = goodsIdList.stream().map(Long::valueOf).collect(Collectors.toList());

        if(Collections3.isEmpty(goodsIds)) return false;
        ResponseResult<List<GoodsDTO>> responseResult = goodsFeignBClient.listByGoods(goodsIds);
        DataUtils.trueThrowException(!ResponseCodeEnum.SUCCESS.getCode().equals(responseResult.getCode()), responseResult.getMsg());
        List<GoodsDTO> goodsDTOS = responseResult.getData();

        if(Collections3.isEmpty(goodsDTOS)) return false;
        BroadcastGoodsQuery query = new BroadcastGoodsQuery();
        query.setPublishStatus(PublishStatusEnum.ENABLE.getValue());
        //List<BroadcastGoodsVO> savedBroadcastGoodsVOS = this.getBean().list(query);
        //Map<Long, String> articleCountMap = savedBroadcastGoodsVOS.stream().collect(Collectors.toMap(BroadcastGoodsVO::getId,BroadcastGoodsVO::getGoodsName));
        List<BroadcastGoodsDO> broadcastGoodsDOS = new ArrayList<BroadcastGoodsDO>();
        broadcastGoodsDOS = goodsDTOS.stream().map(d->{
           // if(articleCountMap.containsKey(d.getId())) {
            BroadcastGoodsDO broadcastGoodsDO = new BroadcastGoodsDO();
            broadcastGoodsDO.setId(IdGenerator.getId());
            broadcastGoodsDO.setGoodsId(d.getId());
            broadcastGoodsDO.setGoodsName(d.getName());
            broadcastGoodsDO.setGoodsPriceType(BroadcastGoodsPriceTypeEnum.PRICE_TYPE_FIXED.getValue());
            broadcastGoodsDO.setGoodsPrice(d.getPrice());
            broadcastGoodsDO.setGoodsThumb(d.getThumb());
            broadcastGoodsDO.setGoodsPagePath(d.getPagePath());
            broadcastGoodsDO.setPublishStatus(PublishStatusEnum.DISABLE.getValue());
            broadcastGoodsDO.setCreateBy(UserUtils.getUserId());
            broadcastGoodsDO.setCreateTime(LocalDateTime.now());
            broadcastGoodsDO.setModifyTime(LocalDateTime.now());
            return broadcastGoodsDO;

        }).collect(Collectors.toList());
        LogUtils.info("==========broadcastGoodsDOS:{}===========",JsonUtils.toJsonStr(broadcastGoodsDOS));
        return broadcastGoodsMapper.insertBatchSomeColumn(broadcastGoodsDOS) > 0;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean modify(BroadcastGoodsParam param) {
        checkUnique(param);
        BroadcastGoodsDO broadcastGoodsDO = BeanUtil.convertBean(param, BroadcastGoodsDO.class);
        broadcastGoodsDO.setModifyBy(UserUtils.getUserId());
        broadcastGoodsDO.setModifyTime(LocalDateTime.now());
        return broadcastGoodsMapper.updateById(broadcastGoodsDO) > 0;
    }

    @Override
    public BroadcastGoodsVO view(Long id) {
        BroadcastGoodsDO broadcastGoodsDO = broadcastGoodsMapper.selectById(id);
        BroadcastGoodsVO broadcastGoodsVO = JsonUtils.fromJson(broadcastGoodsDO, BroadcastGoodsVO.class);
        return broadcastGoodsVO;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean del(Long id) {
        return broadcastGoodsMapper.deleteById(id) > 0;
    }
    /***
     * 发布状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean changePublishStatus(Long id, Integer status) {
        BroadcastGoodsDO broadcastGoodsDO = broadcastGoodsMapper.selectById(id);
        broadcastGoodsDO.setId(id);
        broadcastGoodsDO.setPublishStatus(status);

        broadcastGoodsDO.setModifyTime(LocalDateTime.now());
//        if (PublishStatusEnum.ENABLE.getValue().equals(status)) {
//            broadcastGoodsDO.setPublishTime(LocalDateTime.now());
//        }
        /**
         * 只有点发布时候，才能把商品信息推送到微信直播平台
         */
        if(status.intValue() == PublishStatusEnum.ENABLE.getValue()) {
            WxMaLiveGoodInfo wxMaLiveGoodInfo = new WxMaLiveGoodInfo();
            wxMaLiveGoodInfo.setCoverImgUrl(broadcastGoodsDO.getGoodsImg());
            wxMaLiveGoodInfo.setName(broadcastGoodsDO.getGoodsName());
            wxMaLiveGoodInfo.setPrice(new BigDecimal(broadcastGoodsDO.getGoodsPrice()));
            wxMaLiveGoodInfo.setPrice2(new BigDecimal(broadcastGoodsDO.getGoodsPrice2()));
            wxMaLiveGoodInfo.setPriceType(broadcastGoodsDO.getGoodsPriceType());
            wxMaLiveGoodInfo.setUrl(broadcastGoodsDO.getGoodsPagePath());
            WxMaLiveResult wxMaLiveResult = wxBroadcastServiceImpl.addGoods(wxMaLiveGoodInfo);
            if ((wxMaLiveResult == null) || (wxMaLiveResult.getGoodsId() <= 0)) {
                throw new BusinessException("向直播平台发布商品失败");
            }
            broadcastGoodsDO.setGoodsId(wxMaLiveResult.getGoodsId().longValue());
            broadcastGoodsDO.setAuditId(wxMaLiveResult.getAuditId());
        }else{
            /**
             * 如果下架，则删除微信直播平台的商品
             */
            Long goodsId = broadcastGoodsDO.getGoodsId();
            WxMaLiveResult.Goods goods = wxBroadcastServiceImpl.getGoodsInfo(goodsId.intValue());
            if (goods == null) {
                throw new BusinessException("向直播平台发布商品失败");
            }
            boolean result = wxBroadcastServiceImpl.delGoods(goodsId.intValue());
            if (!result) {
                throw new BusinessException("向直播平台发布商品失败");
            }
        }
        return broadcastGoodsMapper.updateById(broadcastGoodsDO) > 0;
    }
    /**
     * 校验唯一性
     *
     * @param param
     */
    public void checkUnique(BroadcastGoodsParam param) {
        LambdaQueryWrapper<BroadcastGoodsDO> queryWrapper = new LambdaQueryWrapper<BroadcastGoodsDO>()
                .ne(param.getId() != null, BroadcastGoodsDO::getId, param.getId())
                .eq(StringUtils.isNotBlank(param.getGoodsName()), BroadcastGoodsDO::getGoodsName, param.getGoodsName());
        List<BroadcastGoodsDO> dos = broadcastGoodsMapper.selectList(queryWrapper);
        if (Collections3.isNotEmpty(dos)) {
            throw new BusinessException("已经存在相同名字的商品!");
        }
    }
    private BroadcastGoodsServiceImpl getBean() {
        return SpringBeanUtil.getBean(this.getClass());
    }
}
